(function (zn){

    //======attrHooks start======//
    var attrHooks = {
        value: {
            set: function (dom, value) {
                var _type = dom.type;

                switch (_type) {
                    case 'checkbox':
                    case 'radio':
                        dom.checked = !!value;
                        break;
                    default:
                        dom.value = value;
                }
            },
            get: function (dom) {
                var _type = dom.type,
                    _value = dom.value;

                switch (_type) {
                    case 'checkbox':
                    case 'radio':
                        _value = !!dom.checked;
                        break;
                    default:
                        _value = dom.value;
                }

                return _value;
            }
        }
    };
    var baseAttrHooks = {
        'style': 'style.cssText',
        'class': 'className',
        'for': 'htmlFor'
    };
    var booleanAttrHooks = {
        disabled: 'disabled',
        readonly: 'readonly',
        checked: 'checked'
    };
    //registerAttrHooks for Element

    var __setPathValue = function (target, path, value){
        var _tokens = path.split('.'),
            _handle = target;
        for(var i= 0, _len = _tokens.length; i<_len; i++){
            if(!_handle){ return false; }
            if(i == _len-1){
                _handle[_tokens[i]] = value;
            }else {
                _handle = _handle[_tokens[i]];
            }
        }
    }

    //baseAttrHooks
    zn.each(baseAttrHooks,function (hookValue,hookKey) {
        attrHooks[hookKey] = {
            set: function (dom, value) {
                if(hookValue.indexOf('.') === -1){
                    dom[hookValue] = value;
                }else {
                    __setPathValue(dom, hookValue, value);
                }
            },
            get: function (dom) {
                return dom[hookValue];
            }
        };
    });

    //booleanAttrHooks
    zn.each(booleanAttrHooks,function (hookValue,hookKey) {
        attrHooks[hookKey] = {
            set: function (dom, value) {
                if (!value) {
                    dom.removeAttribute(hookKey);
                } else {
                    dom.setAttribute(hookKey,hookKey);
                }

                dom[hookValue] = !!value;
            },
            get: function (dom) {
                return !!dom[hookValue];
            }
        };
    });

    //======attrHooks end ======//

    /**
     * @class DOM
     * @namespace zn.ui.dom
     * @desc The element for dom.
     */
    zn.class('zn.ui.dom.DOM', zn.ui.core.Element, {
        partial: true,
        methods: {
            setAttribute: function (name, value) {
                var _dom = this._dom,
                    _hook = attrHooks[name];

                if (_hook) {
                    if (_hook.set) {
                        return _hook.set(_dom, value);
                    } else {
                        return _dom.setAttribute(_hook, value);
                    }
                }

                return _dom.setAttribute(name, value);
            },
            getAttribute: function (name) {
                var _dom=this._dom,
                    _hook = attrHooks[name];

                if (_hook) {
                    if (_hook.get) {
                        return _hook.get(_dom);
                    } else {
                        return _dom.getAttribute(_hook);
                    }
                }

                return _dom.getAttribute(name);
            },
            removeAttribute: function (name) {
                return this._dom.removeAttribute(baseAttrHooks[name] || name), this;
            },
            getAttributes: function () {
                var _attrs = {};
                zn.each(this._dom.attributes,function (attr) {
                    _attrs[attr.name] = attr.value;
                });

                return _attrs;
            },
            setAttributes: function (attrs) {
                zn.each(attrs,function (value, key) {
                    this.setAttribute(key, value);
                }, this);

                return this;
            }
        }
    });

})(zn);
